package com.wxzz.elearing.pay.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wxzz.elearing.pay.amqp.producer.PayMessageProducer;
import com.wxzz.elearing.pay.dto.CheckUserWithdrawDepositDto;
import com.wxzz.elearing.pay.dto.SendUserWithdrawDepositDto;
import com.wxzz.elearing.pay.dto.UserBankCardDto;
import com.wxzz.elearing.pay.dto.UserWithdrawDepositDto;
import com.wxzz.elearing.pay.entity.UserBankCard;
import com.wxzz.elearing.pay.entity.UserTransaction;
import com.wxzz.elearing.pay.entity.UserWallet;
import com.wxzz.elearing.pay.entity.UserWithdrawDeposit;
import com.wxzz.elearing.pay.mapper.UserBankCardMapper;
import com.wxzz.elearing.pay.mapper.UserTransactionMapper;
import com.wxzz.elearing.pay.mapper.UserWalletMapper;
import com.wxzz.elearing.pay.mapper.UserWithdrawDepositMapper;
import com.wxzz.elearing.pay.service.IUserTransactionService;
import com.wxzz.elearing.pay.service.IUserWalletService;
import com.wxzz.elearing.pay.service.IUserWithdrawDepositService;
import com.wxzz.elearing.pay.service.openfeign.IDocentFeign;
import com.wxzz.elearing.pay.service.openfeign.IEnterpriseFeign;
import com.wxzz.elearing.pay.service.openfeign.IWxUserApiFeign;
import com.wxzz.elearning.common.aop.Idempotent;
import com.wxzz.elearning.common.bean.SmsConfig;
import com.wxzz.elearning.common.dto.FeignEnterpriseDto;
import com.wxzz.elearning.common.dto.FeignWxUserDto;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.utils.OpenFeignUtil;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * <p>
 * 用户提现记录 服务实现类
 * </p>
 *
 * @author
 * @since 2021-04-23
 */
@Service
public class UserWithdrawDepositServiceImpl extends ServiceImpl<UserWithdrawDepositMapper, UserWithdrawDeposit> implements IUserWithdrawDepositService {

    @Autowired
    private UserWithdrawDepositMapper userWithdrawDepositMapper;

    @Autowired
    private UserBankCardMapper userBankCardMapper;

    @Autowired
    private UserWalletMapper userWalletMapper;

    @Autowired
    private IUserWalletService userWalletService;

    @Autowired
    private UserTransactionMapper userTransactionMapper;

    @Idempotent
    @Transactional
    @Override
    public ReturnVO sendUserWithdrawDeposit(JSONObject jsonObject, SendUserWithdrawDepositDto sendUserWithdrawDepositDto) {
        if (sendUserWithdrawDepositDto.getUserType() == null) {
            throw new ServiceException("请传入用户类型");
        }
        UserBankCard userBankCard = userBankCardMapper.selectById(sendUserWithdrawDepositDto.getUserBankCardId());
        Optional.ofNullable(userBankCard).orElseThrow(() -> new ServiceException("该银行卡不存在"));
        //提现次数+1
        userBankCard.setWithdrawDepositNum(userBankCard.getWithdrawDepositNum() + 1);
        userBankCardMapper.updateById(userBankCard);
        UserWithdrawDeposit userWithdrawDeposit = new UserWithdrawDeposit();
        BeanUtils.copyProperties(userBankCard, userWithdrawDeposit);
        userWithdrawDeposit.setId(null);
        userWithdrawDeposit.setUserType(sendUserWithdrawDepositDto.getUserType());
        Long userId = 0L;
        //查询用户对应id
        if (sendUserWithdrawDepositDto.getUserType() == 0) {
            //平台
            userId = 0L;
        }
        if (sendUserWithdrawDepositDto.getUserType() == 1) {
            //管理端
            userId = jsonObject.getLong("enterpriseId");
        }
        if (sendUserWithdrawDepositDto.getUserType() == 2) {
            //客户端
            userId = jsonObject.getLong("id");
        }
        if (sendUserWithdrawDepositDto.getUserType() == 3) {
            //讲师端
            userId = jsonObject.getLong("docentId");
        }
        userWithdrawDeposit.setUserId(userId);
        UserWallet userWallet = userWalletMapper.selectOne(new LambdaQueryWrapper<UserWallet>()
                .eq(UserWallet::getUserType, sendUserWithdrawDepositDto.getUserType())
                .eq(UserWallet::getUserId, userId));
        Optional.ofNullable(userWallet).orElseThrow(() -> new ServiceException("该用户没有钱包"));
        if (userWallet.getUserBalance().compareTo(sendUserWithdrawDepositDto.getPrice()) == -1) {
            throw new ServiceException("用户钱包余额不足");
        }
        userWallet.setWithdrawNum(userWallet.getWithdrawNum() + 1);
        userWallet.setWithdrawMoney(sendUserWithdrawDepositDto.getPrice().add(userWallet.getWithdrawMoney()));
        userWalletMapper.updateById(userWallet);
        //提现金额
        userWithdrawDeposit.setPrice(sendUserWithdrawDepositDto.getPrice());
        userWithdrawDepositMapper.insert(userWithdrawDeposit);
        //用户余额变动
        UserTransaction userTransaction = new UserTransaction();
        userTransaction.setMoney(sendUserWithdrawDepositDto.getPrice().negate());
        UserWallet resultUserWallet = userWalletService.updateUserWallet(userId, sendUserWithdrawDepositDto.getUserType(), sendUserWithdrawDepositDto.getPrice().negate());
        userTransaction.setBalance(resultUserWallet.getUserBalance());
        userTransaction.setDescription("提现申请");
        userTransaction.setBusinessRemark("申请id:" + userWithdrawDeposit.getId());
        userTransaction.setUserType(sendUserWithdrawDepositDto.getUserType());
        userTransaction.setType(2);
        userTransaction.setUserId(userId);
        userTransaction.setUsername(userTransactionService.getUserName(sendUserWithdrawDepositDto.getUserType(), userId));
        userTransaction.setTransactionStatus("扣除余额");
        userTransaction.setChangeType("提现申请");
        userTransactionMapper.insert(userTransaction);
        //平台余额变动
        UserTransaction userTransaction4platform = new UserTransaction();
        userTransaction4platform.setMoney(sendUserWithdrawDepositDto.getPrice());
        UserWallet resultUserWallet4platform = userWalletService.updateUserWallet(0L, 0, sendUserWithdrawDepositDto.getPrice());
        userTransaction4platform.setBalance(resultUserWallet4platform.getUserBalance());
        userTransaction4platform.setDescription("提现申请");
        userTransaction4platform.setBusinessRemark("申请id:" + userWithdrawDeposit.getId());
        userTransaction4platform.setUserType(0);
        userTransaction4platform.setType(2);
        userTransaction4platform.setUserId(0L);
        userTransaction4platform.setUsername(userTransactionService.getUserName(0, 0L));
        userTransaction4platform.setTransactionStatus("存入余额");
        userTransaction4platform.setChangeType("提现申请");
        userTransactionMapper.insert(userTransaction4platform);

        String name = "";
        //发送平台消息
        if (userTransaction.getUserType() == 1) {
            FeignEnterpriseDto feignEnterpriseDto = enterpriseFeign.selectEnterpriseDtoById(userTransaction.getUserId());
            name = name + feignEnterpriseDto.getEnterpriseName();
        }
        if (userTransaction.getUserType() == 2) {
            FeignWxUserDto feignWxUserDto = wxUserApiFeign.selectFeignWxUserDtoByWxUserId(userTransaction.getUserId());
            name = name + feignWxUserDto.getEnterpriseName();
        }
        if (userTransaction.getUserType() == 3) {
            ReturnVO<String> stringReturnVO = docentFeign.selectDocentById(userTransaction.getUserId());
            JSONObject docent = OpenFeignUtil.getJSONObject(stringReturnVO);
            if (docent != null) {
                name = name + docent.getString("docentName");
            }
        }
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        systemMessageMqDto.setMessageDetail(name + "发起了提现申请，请及时审核");
        systemMessageMqDto.setMessageTitle("提现申请");
        systemMessageMqDto.setMessageType(2);
        systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
            {
                add(0L);
            }
        });
        payMessageProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        return new ReturnVO("提现申请发起成功", userWithdrawDeposit.getId());
    }

    @Autowired
    private IEnterpriseFeign enterpriseFeign;

    @Autowired
    private IWxUserApiFeign wxUserApiFeign;

    @Autowired
    private IDocentFeign docentFeign;

    @Autowired
    private PayMessageProducer payMessageProducer;

    @Override
    public ReturnVO<JgPageVo<List<UserWithdrawDeposit>>> listUserWithdrawDeposit(UserWithdrawDepositDto userWithdrawDepositDto) {
        PageHelper.startPage(userWithdrawDepositDto.getCurPage(), userWithdrawDepositDto.getMaxPage());
        QueryWrapper<UserWithdrawDeposit> queryWrapper = new QueryWrapper<>();
        if (userWithdrawDepositDto.getUserType() != null) {
            queryWrapper.eq("user_type", userWithdrawDepositDto.getUserType());
        }
        if (userWithdrawDepositDto.getStatus() != null) {
            queryWrapper.eq("status", userWithdrawDepositDto.getStatus());
        }
        if (StringUtils.isNotBlank(userWithdrawDepositDto.getBankCardNum())) {
            queryWrapper.like("bank_card_num", userWithdrawDepositDto.getBankCardNum() + "%");
        }
        if (StringUtils.isNotBlank(userWithdrawDepositDto.getPersonName())) {
            queryWrapper.like("person_name", userWithdrawDepositDto.getPersonName() + "%");
        }
        if (StringUtils.isNotBlank(userWithdrawDepositDto.getPhone())) {
            queryWrapper.like("phone", userWithdrawDepositDto.getPhone() + "%");
        }
        if (StringUtils.isNotBlank(userWithdrawDepositDto.getCheckUsername())) {
            queryWrapper.like("check_username", userWithdrawDepositDto.getCheckUsername() + "%");
        }
        if (StringUtils.isNotBlank(userWithdrawDepositDto.getBankName())) {
            queryWrapper.like("bank_name", userWithdrawDepositDto.getBankName() + "%");
        }
        if (userWithdrawDepositDto.getStartTime() != null && userWithdrawDepositDto.getEndTime() != null) {
            queryWrapper.between("create_time", userWithdrawDepositDto.getStartTime(), userWithdrawDepositDto.getEndTime());
        }
        List<UserWithdrawDeposit> userWithdrawDeposits = userWithdrawDepositMapper.selectList(queryWrapper);
        return new ReturnVO("提现申请列表查询成功", new JgPageVo<>(new PageInfo(userWithdrawDeposits)));
    }

    @Idempotent
    @Transactional
    @Override
    public ReturnVO checkUserWithdrawDeposit(JSONObject jsonObject, CheckUserWithdrawDepositDto checkUserWithdrawDepositDto) {
        UserWithdrawDeposit userWithdrawDeposit = userWithdrawDepositMapper.selectById(checkUserWithdrawDepositDto.getUserWithdrawDepositId());
        Optional.ofNullable(userWithdrawDeposit).orElseThrow(() -> new ServiceException("该提现申请不存在"));
        if (userWithdrawDeposit.getStatus() != 0) {
            throw new ServiceException("该记录已经被审核");
        }
        //设置审核信息
        userWithdrawDeposit.setRemark(checkUserWithdrawDepositDto.getRemark());
        userWithdrawDeposit.setCheckUsername(jsonObject.getString("username"));
        //提现成功
        if (checkUserWithdrawDepositDto.getStatus() == 1) {
            userWithdrawDeposit.setStatus(1);
            //如果是用户端
            if (userWithdrawDeposit.getUserType() == 2) {
                SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
                systemMessageMqDto.setPhones(new ArrayList<String>() {
                    {
                        add(userWithdrawDeposit.getPhone());
                    }
                });
                systemMessageMqDto.setTemplateId(SmsConfig.withdrawDepositId);
                systemMessageMqDto.setParams(new ArrayList<String>() {
                    {
                        add(userWithdrawDeposit.getPrice().toString());
                    }
                });
                systemMessageMqDto.setMessageDetail("您的提现申请已经审核通过,提现金额" + userWithdrawDeposit.getPrice() + "请及时查收");
                systemMessageMqDto.setMessageTitle("提现成功");
                systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                    {
                        add(userWithdrawDeposit.getUserId());
                    }
                });
                payMessageProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
            }
        }
        //提现失败
        if (checkUserWithdrawDepositDto.getStatus() == 2) {
            userWithdrawDeposit.setStatus(2);
            //流水变动
            //用户余额变动
            UserTransaction userTransaction = new UserTransaction();
            userTransaction.setMoney(userWithdrawDeposit.getPrice());
            UserWallet resultUserWallet = userWalletService.updateUserWallet(userWithdrawDeposit.getUserId(), userWithdrawDeposit.getUserType(), userWithdrawDeposit.getPrice());
            userTransaction.setBalance(resultUserWallet.getUserBalance());
            userTransaction.setDescription("提现审核失败");
            userTransaction.setBusinessRemark("申请id:" + userWithdrawDeposit.getId());
            userTransaction.setUserType(userWithdrawDeposit.getUserType());
            userTransaction.setType(2);
            userTransaction.setUserId(userWithdrawDeposit.getUserId());
            userTransaction.setUsername(userTransactionService.getUserName(userWithdrawDeposit.getUserType(), userWithdrawDeposit.getUserId()));
            userTransaction.setTransactionStatus("存入余额");
            userTransaction.setChangeType("提现申请");
            userTransactionMapper.insert(userTransaction);
            //平台余额变动
            UserTransaction userTransaction4platform = new UserTransaction();
            userTransaction4platform.setMoney(userWithdrawDeposit.getPrice().negate());
            UserWallet resultUserWallet4platform = userWalletService.updateUserWallet(0L, 0, userWithdrawDeposit.getPrice().negate());
            userTransaction4platform.setBalance(resultUserWallet4platform.getUserBalance());
            userTransaction4platform.setDescription("提现审核失败");
            userTransaction4platform.setBusinessRemark("申请id:" + userWithdrawDeposit.getId());
            userTransaction4platform.setUserType(0);
            userTransaction4platform.setType(2);
            userTransaction4platform.setUserId(0L);
            userTransaction4platform.setUsername(userTransactionService.getUserName(0, 0L));
            userTransaction4platform.setTransactionStatus("归还余额");
            userTransaction4platform.setChangeType("提现申请");
            userTransactionMapper.insert(userTransaction4platform);
        }
        userWithdrawDepositMapper.updateById(userWithdrawDeposit);
        return new ReturnVO("提现记录审核成功", userWithdrawDeposit.getId());
    }

    @Autowired
    private IUserTransactionService userTransactionService;

}
